
// INCLUDES ********************************************************************

#include "Vector2D.h"


// NAMESPACES ******************************************************************

using namespace Meteor;

#pragma mark -
#pragma mark Constructors
// -----------------------------------------------------------------------------

Vector2D::Vector2D( const float& x, const float& y)

: mX( x), mY( y)
{
}

// -----------------------------------------------------------------------------

Vector2D::Vector2D( const CGPoint& point) : mX( point.x), mY( point.y)
{
}

// -----------------------------------------------------------------------------

Vector2D::Vector2D( const Vector2D& rhs)
{
    mX = rhs.X();
    mY = rhs.Y();
}

// -----------------------------------------------------------------------------

Vector2D& Vector2D::operator=( const Vector2D& rhs)
{
    if ( this == &rhs)
    {
        return *this;
    }
    
    mX = rhs.X();
    mY = rhs.Y();
    
    return *this;
}

#pragma mark -
#pragma mark Mathematical operations
// -----------------------------------------------------------------------------

const float Vector2D::operator*( const Vector2D& rhs) const
{
    return ( mX * rhs.X()) + ( mY * rhs.Y());
}

// -----------------------------------------------------------------------------

const Vector2D Vector2D::operator*( const float& scalar) const
{
    return Vector2D( mX*scalar, mY*scalar);
}

// -----------------------------------------------------------------------------


const Vector2D Vector2D::operator+( const Vector2D& rhs) const
{
    return Vector2D( mX + rhs.X(), mY + rhs.Y());
}

// -----------------------------------------------------------------------------


const Vector2D Vector2D::operator-( const Vector2D& rhs) const
{
    return Vector2D( mX - rhs.X(), mY - rhs.Y());
}

// -----------------------------------------------------------------------------

const Vector2D Vector2D::operator+=( const Vector2D& rhs)
{
    mX = mX + rhs.X();
    mY = mY + rhs.Y();

    return *this;
}

// -----------------------------------------------------------------------------

const Vector2D Vector2D::operator-=( const Vector2D& rhs)
{
    mX = mX - rhs.X();
    mY = mY - rhs.Y();
    
    return *this;
}

// -----------------------------------------------------------------------------

const bool Vector2D::operator==( const Vector2D& rhs) const
{
   if ( mX == rhs.mX && mY == rhs.mY)
   {
       return true;
   }
   else 
   {
       return false;
   }

}

// -----------------------------------------------------------------------------

const bool Vector2D::operator!=( const Vector2D& rhs) const
{
   if ( mX != rhs.mX || mY != rhs.mY)
   {
       return true;
   }
   else 
   {
       return false;
   }

}
    
// -----------------------------------------------------------------------------

const float Vector2D::Length() const
{
    return sqrt( pow( mX, 2) + pow( mY, 2) );
}   

// -----------------------------------------------------------------------------

const Vector2D& Vector2D::Normalize()
{
    float vectorLength = Length();

    if ( vectorLength != 0.0f)
    {
        mX = mX / vectorLength;
        mY = mY / vectorLength;
    }
   
    return *this;
}

#pragma mark -
#pragma mark Setter/getter
// -----------------------------------------------------------------------------

const float Vector2D::X() const
{
    return mX;
}

// -----------------------------------------------------------------------------

const float Vector2D::Y() const
{
    return mY;
}

// -----------------------------------------------------------------------------

void Vector2D::SetX( const float newX)
{
    mX = newX;
}

// -----------------------------------------------------------------------------
    
void Vector2D::SetY( const float newY)
{
    mY = newY;
}


#pragma mark -
#pragma mark Helper functions
// -----------------------------------------------------------------------------

const float Vector2D::Angle( Vector2D& lhs, Vector2D& rhs)
{
    return acos( ( lhs * rhs ) / ( lhs.Length() * rhs.Length() ) );
}

// -----------------------------------------------------------------------------

const float Vector2D::Distance( const Vector2D& lhs, const Vector2D& rhs)
{
    float deltaX = rhs.X() - lhs.X();
    float deltaY = rhs.Y() - lhs.Y();
    
    return sqrt( pow( deltaX, 2) + pow( deltaY, 2) );
}
